package com.jz.netthings.engine.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.jy.faceValidate.utils.FaceValidateUtils;
import com.jz.netthings.appengine.baseData.MachineData;
import com.jz.netthings.appengine.baseData.ProviderData;
import com.jz.netthings.appengine.baseData.ProviderInfo;
import com.jz.netthings.appengine.mapper.ProviderInfoMapper;
import com.jz.netthings.appengine.queue.ChairMgr;
import com.jz.netthings.appengine.queue.MachineMgr;
import com.jz.netthings.appengine.queue.ProviderQueue;
import com.jz.netthings.appengine.support.BeanSupport;
import com.jz.netthings.appengine.support.SendMsgSupport;
import com.jz.netthings.application.providerCollection.bean.ProviderCollection;
import com.jz.netthings.application.providerCollection.mapper.mysql.ProviderCollectionMapper;
import com.jz.netthings.application.providerCollection.service.ProviderCollectionService;
import com.jz.netthings.application.upload.service.UploadService;
import com.jz.netthings.bean.system.JyUser;
import com.jz.netthings.engine.service.ClientService;
import com.jz.netthings.engine.service.ZxdcService;
import com.jz.netthings.netty.protocol.bean.ZxdcLoginPacket;
import com.jz.netthings.netty.protocol.bean.ZxdcMsgPacket;
import com.jz.netthings.netty.utils.NettyMsgHelper;
import com.jz.netthings.system.mapper.mysql.JyUserMapper;
import com.jz.netthings.system.utils.AdscmSystemUtils;
import com.jz.netthings.utils.AdscmBaseUtils;
import com.jz.netthings.utils.AdscmDateUtils;
import com.jz.netthings.utils.TextUnit;
import io.netty.channel.ChannelHandlerContext;
import javafx.beans.binding.ObjectBinding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service("zxdcService")
public class ZxdcServiceImpl implements ZxdcService {

    public static String[] zxdcStatus = {
            "护士登陆", "自检", "互检", "自检完成", "安装耗材", "预充", "献浆员登陆", "加压", "穿刺", "采集" , "还输", "采浆结束", "取耗材开始", "取耗材结束"
    };
    /**
     * 采集状态
     */
    public static String[] collStatus = {
             "","第一层采浆开始", "第二层采浆开始","第三层采浆开始",  "第四层采浆开始", "第五层采浆开始",
            "第六层采浆开始",  "第七层采浆开始", "第八层采浆开始", "第九层采浆开始",
            "第十层采浆开始", "第十一层采浆开始",  "第十二层采浆开始",  "第十三层采浆开始",
            "第十四层采浆开始", "第十五层采浆开始",  "第十六层采浆开始",  "第十七层采浆开始",
            "第十八层采浆开始",  "第十九层采浆开始",  "第二十层采浆开始"
    };
    /**
     * 还输状态
     */
    public static String[] hsStatus = {
            "", "第一层还输开始", "第二层还输开始","第三层还输开始",  "第四层还输开始", "第五层还输开始",
            "第六层还输开始",  "第七层还输开始", "第八层还输开始", "第九层还输开始",
            "第十层还输开始", "第十一层还输开始",  "第十二层还输开始",  "第十三层还输开始",
            "第十四层还输开始", "第十五层还输开始",  "第十六层还输开始",  "第十七层还输开始",
            "第十八层还输开始",  "第十九层还输开始",  "第二十层还输开始"
    };

    public static String getZxdcStatusText(int idx,int targetIdx) {
        if (idx < 0) {
            return "";
        }
        if (idx >= zxdcStatus.length) {
            return "";
        }
        if (idx == 9){
            if (targetIdx < 0) {
                return "";
            }
            if (targetIdx >= collStatus.length) {
                return "";
            }
            return  collStatus[targetIdx];
        }
        if (idx == 10){
            if (targetIdx < 0) {
                return "";
            }
            if (targetIdx >= hsStatus.length) {
                return "";
            }
            return  hsStatus[targetIdx];
        }
        return zxdcStatus[idx];
    }

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    RedisTemplate<Object , Object> objectRedisTemplate;
    @Autowired
    JyUserMapper jyUserMapper;
    @Autowired
    ProviderQueue providerQueue;
    @Autowired
    ProviderInfoMapper providerInfoMapper;
    @Autowired
    ProviderCollectionMapper providerCollectionMapper;
    @Autowired
    ClientService clientService;
    @Autowired
    UploadService uploadService;
    @Value("${ly.upload.baseUrl}")
    String  photoUrl;

    @Value("${jz.zxdc.faceValidateNum}")
    private String faceValidateNum;

    @Override
    public void handlerLoginPacket(ZxdcLoginPacket packet) {

        String apCode = packet.getApCode();
        System.out.println("apCode ：" + apCode);
        if (apCode.indexOf("chair") >= 0){
            //证明是平板登录
            logger.info("平板【"+apCode+"】登录...");
            ChairMgr.getInstance().bindCtxChair(apCode,packet.getCtx());
        }else {
            try {
                //绑定
                MachineMgr.getInstance().bindCtxMac(packet.getApCode(), packet.getCtx());

                MachineData machine = MachineMgr.getInstance().getMachine(packet.getApCode());

                synchronized (MachineMgr.getInstance()) {
                    machine.setOnline(true);
                    MachineMgr.getInstance().updateRedisMachineData(objectRedisTemplate,machine);
                }

            } catch (Exception e) {
                logger.error("单采机登录信息处理失败", e);
            }
        }


    }

    @Override
    public ZxdcMsgPacket handlerMsgPacket(ZxdcMsgPacket packet) {

        ZxdcMsgPacket targetPacket = null;

        if ("cur_sys_state".equals(packet.getCmd())) {
            this.doZxdcStatus(packet);
        } else if ("nurse_register".equals(packet.getCmd())) {
            targetPacket = this.doNurseRegister(packet);
        } else if ("start_install_cm".equals(packet.getCmd())) {
            targetPacket = this.doStartInstallCm(packet);
        } else if ("end_install_cm".equals(packet.getCmd())){
            targetPacket = this.doFinishInstallCm(packet);
        } else if ("get_XJDZC_weight".equals(packet.getCmd())){
            targetPacket = this.doWeight(packet);
        }else if ("response".equals(packet.getCmd())){
            this.doAllocDonor(packet);
        }else if ("collect_plasma_record".equals(packet.getCmd())){
            this.doRecordCollectPlasma(packet);
        }else if ("start_inflating".equals(packet.getCmd())){
            this.doStartInflating(packet);
        }else if ("start_puncture".equals(packet.getCmd())){
            this.doStartPuncture(packet);
        }else if("end_puncture".equals(packet.getCmd())){
            this.doFinishPuncture(packet);
        }else if ("start_collect_plasma".equals(packet.getCmd())){
            this.doStartCollectPlasma(packet);
        }else if ("HS_start_time".equals(packet.getCmd())){
            this.doStartHs(packet);
        }else if ("HS_end_time".equals(packet.getCmd())){
            this.doEndHs(packet);
        }else if ("finished_collect_plasma".equals(packet.getCmd())){
            this.doFinishedCollectPlasma(packet);
        }else if ("pause_plasma_draw".equals(packet.getCmd())){
            this.doPausePlasmaReturn(packet);
        }else if ("pause_plasma_return".equals(packet.getCmd())){
            this.doResumePlasmaReturn(packet);
        }else if ("pipe_pressusre_low".equals(packet.getCmd())){
            this.doPipePressusreLow(packet);
        }else if ("pipe_pressusre_normal".equals(packet.getCmd())){
            this.doPipePressusreNormal(packet);
        }else if ("auth_request".equals(packet.getCmd())){
            this.doAuthRequest(packet);
        }else if ("faceRecognition".equals(packet.getCmd())){
            targetPacket = this.faceRecognition(packet);
        }

        return targetPacket;
    }

    /**
     * 单采机的人脸认证
     * @param packet
     * @return
     */
    private ZxdcMsgPacket faceRecognition(ZxdcMsgPacket packet){
        ZxdcMsgPacket targetPacket = new ZxdcMsgPacket();
        try{
            HashMap<String, Object> values = packet.getValues();
            Object donorId = values.get("donorId");
            Object faceStr = values.get("face");

            if (AdscmBaseUtils.getInstance().isNotEmpty(donorId,null) && donorId instanceof String){
                if (faceStr instanceof String){
                    byte[] face = Base64.getDecoder().decode((String)faceStr);
//                    targetPacket = EngineSupport.faceRecognition((String) donorId, face,packet.getSeq(),packet.getCmd(),clientService,logger);
                    logger.info("开始进行【" + donorId + "】的人脸认证...");
                    String[] path = clientService.getImgsPath( (String) donorId, face);

                    if (path[0] != null && path[1] != null) {
                        float result = FaceValidateUtils.validateImg(path[0], path[1]);

                        boolean flag = false;
                        logger.info("标准阈值【"+faceValidateNum+"】，比对阈值【"+result+"】");
                        if (result >= new Float(faceValidateNum)){
                            flag = true;
                            //将认证通过的人脸保存到库中
                            String collFacePath = uploadService.uploadImageByBytes(face);
                            Wrapper<ProviderCollection> wrapper = new EntityWrapper<>();
                            ProviderData providerData = providerQueue.getByProviderNo((String) donorId);
                            if (providerData != null){
                                wrapper.eq("providerNo",providerData.getProviderId());
                                wrapper.eq("registerNo",providerData.getRegisterNo());
                                List<ProviderCollection> collections = providerCollectionMapper.selectList(wrapper);
                                if (collections != null && collections.size()>0){
                                    for (ProviderCollection collection : collections) {
                                        collection.setCollPhoto(collFacePath);
                                        providerCollectionMapper.updateById(collection);
                                    }
                                }
                            }
                        }

                        targetPacket.setSeq(packet.getSeq());
                        targetPacket.setCmd("response");
                        targetPacket.setResponseFromCmd(packet.getCmd());
                        values = new HashMap<String, Object>();
                        values.put("result", flag);
                        values.put("donorId", donorId);
                        targetPacket.setValues(values);
                    }
                }
            }

        }catch (Exception e){
            logger.error("单采机人脸认证失败",e);
        }
        return targetPacket;
    }

    /**
     *  管压正常:（发送给平板）
     * @param packet
     */
    private void doPipePressusreNormal(ZxdcMsgPacket packet){
        MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
        if (machine != null){
            logger.info(machine.getCode() + " 管压正常");
            ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
            SendMsgSupport.pipeNormal(chairCxt);
        }

    }
    /**
     *  管压低:（发送给平板）
     * @param packet
     */
    private void doPipePressusreLow(ZxdcMsgPacket packet){
        MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
        if (machine != null){
            logger.info(machine.getCode() + " 管压低");
            ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
            SendMsgSupport.pipeLow(chairCxt);
        }

    }
    /**
     *  恢复采浆:（发送给平板）
     * @param packet
     */
    private void doResumePlasmaReturn(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object pause_plasma_return_time =  values.get("pause_plasma_return_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(pause_plasma_return_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(pause_plasma_return_time.toString()));
                logger.info(machine.getCode() + " 恢复采浆:"+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.resumeCollection(chairCxt,packet);

            }

        }
    }
    /**
     *  暂停采浆:（发送给平板）
     * @param packet
     */
    private void doPausePlasmaReturn(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object pause_plasma_draw_time =  values.get("pause_plasma_draw_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(pause_plasma_draw_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(pause_plasma_draw_time.toString()));
                logger.info(machine.getCode() + " 暂停采浆:"+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.pauseCollection(chairCxt,packet);

            }

        }
    }
    /**
     *  完成采浆（发送给平板）
     * @param packet
     */
    private void doFinishedCollectPlasma(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object plasma_finish_time =  values.get("plasma_finish_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(plasma_finish_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(plasma_finish_time.toString()));
                logger.info(machine.getCode() + " 完成采浆："+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.endCollection(chairCxt);

            }

        }
    }
    /**
     *  结束穿刺（发送给平板）
     * @param packet
     */
    private void doFinishPuncture(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object puncture_end_time =  values.get("puncture_end_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(puncture_end_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(puncture_end_time.toString()));
                logger.info(machine.getCode() + " 结束穿刺："+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.finishPuncture(chairCxt,packet);

            }

        }
    }
    /**
     *  开始还输（发送给平板）
     * @param packet
     */
    private void doEndHs(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object HS_end_time =  values.get("HS_end_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(HS_end_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(HS_end_time.toString()));
                logger.info(machine.getCode() + " 结束还输："+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.autotranfusion_end(chairCxt,packet);

            }

        }
    }
    /**
     *  开始还输（发送给平板）
     * @param packet
     */
    private void doStartHs(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object HS_start_time =  values.get("HS_start_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(HS_start_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(HS_start_time.toString()));
                logger.info(machine.getCode() + " 开始还输："+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.autotranfusion_start(chairCxt,packet);

            }

        }
    }
    /**
     *  开始采浆（发送给平板）
     * @param packet
     */
    private void doStartCollectPlasma(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object plasma_start_time =  values.get("plasma_start_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(plasma_start_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(plasma_start_time.toString()));
                logger.info(machine.getCode() + " 开始采浆："+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.startCollection(chairCxt);

            }

        }
    }

    /**
     *  穿刺（发送给平板）
     * @param packet
     */
    private void doStartPuncture(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object puncture_start_time =  values.get("puncture_start_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(puncture_start_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(puncture_start_time.toString()));
                logger.info(machine.getCode() + " 穿刺："+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.startPuncture(chairCxt,packet);

            }

        }
    }
    /**
     *  加压（发送给平板）
     * @param packet
     */
    private void doStartInflating(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        Object infating_start_time =  values.get("infating_start_time");

        if (AdscmBaseUtils.getInstance().isNotEmpty(infating_start_time, null)) {
            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                Date date = new Date(Long.parseLong(infating_start_time.toString()));
                logger.info(machine.getCode() + " 加压："+ AdscmDateUtils.getDateFomat(date));
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                SendMsgSupport.startInfating(chairCxt,packet);

            }

        }
    }
    /**
     * 单采机请求重新认证
     * @param packet
     */
    private void doAuthRequest(ZxdcMsgPacket packet){
        HashMap<String, Object> values = packet.getValues();
        String donor_no = (String) values.get("donor_no");
        if (AdscmBaseUtils.getInstance().isNotEmpty(donor_no, null)) {


            MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
            if (machine != null){
                ChannelHandlerContext chairCxt = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());

                if (chairCxt != null){
                    ProviderData provider = providerQueue.getByProviderNo(donor_no);
                    ProviderInfo providerInfo = providerInfoMapper.selectById(provider.getProviderId());
                    SendMsgSupport.auth_info(chairCxt,provider,providerInfo);
                }
            }
        }
    }

    /**
     * 单采机采浆完成，上传采浆数据
     *
     * @param packet
     */
    private void doRecordCollectPlasma(ZxdcMsgPacket packet) {

        HashMap<String, Object> values = packet.getValues();
        String donor_id = (String) values.get("donor_id");
        String nurse_id = (String) values.get("nurse_id");

        if (AdscmBaseUtils.getInstance().isNotEmpty(donor_id, null)) {
            ProviderData providerData = providerQueue.getByProviderNo(donor_id);

            String registerNo = providerData.getRegisterNo();

            Wrapper<ProviderCollection> wrapper = new EntityWrapper<>();
            wrapper.eq("providerNo", providerData.getProviderId());
            wrapper.eq("registerNo", registerNo);
            List<ProviderCollection> collections = providerCollectionMapper.selectList(wrapper);

            ProviderCollection collection = null;
            if (collections != null && collections.size() > 0) {
                collection = collections.get(0);
            } else {
                logger.warn("没有获取到浆员[" + donor_id + "]的采浆数据，重新生成采浆数据");
            }
            if (collection == null) {
                collection = new ProviderCollection();
            }
            collection.setIdNo(providerData.getIdNo());
            collection.setProviderNo(providerData.getProviderId() + "");
            collection.setRegisterNo(providerData.getRegisterNo());
            collection.setNurse(nurse_id);

            String logid = values.get("logid").toString();
            if (AdscmBaseUtils.getInstance().isNotEmpty(logid, null)) {
                String macNum = logid.substring(0, 3);
                collection.setMachineNo(macNum);
                collection.setMachineLogId(logid);
            }

            collection.setOperTime(new Date());

            try {
                collection.setStartTime(new Date(Long.parseLong(values.get("collect_plasma_start_time").toString())));
            } catch (Exception e) {
            }
            try {
                collection.setEndTime(new Date(Long.parseLong(values.get("collect_plasma_end_time").toString())));
            } catch (Exception e) {
            }
            try {
                collection.setCollTaken((collection.getEndTime().getTime() - collection.getStartTime().getTime()) / 1000);
            } catch (Exception e) {
            }
            try {
                collection.setHcBatchNo(values.get("FPS_BNO").toString());
            } catch (Exception e) {
            }
            try {
                collection.setKnjBatchNo(values.get("ACD_BNO").toString());
            } catch (Exception e) {
            }
            try {
                collection.setYsBatchNo(values.get("saline_BNO").toString());
            } catch (Exception e) {
            }


            //是否二次穿刺
            collection.setSecondPuncture("true".equals(values.get("second_puncture")));

            //耗材皮重
            try {
                collection.setInitWeight(Integer.parseInt(values.get("plasma_bag_tare").toString()));
            } catch (Exception e) {
            }

            //总采集量
            try {
                collection.setSetTotalNum(Integer.parseInt(values.get("whole_blood_sum").toString()));
            } catch (Exception e) {
            }

            //采浆总量
            try {
                collection.setTotalPlasmaNum(Integer.parseInt(values.get("collect_plasma_sum").toString()));
            } catch (Exception e) {
            }

            //抗凝剂用量
            try {
                collection.setUseKngNum(Float.parseFloat(values.get("knj_sum_used").toString()));
            } catch (Exception e) {
            }

            //盐水用量
            try {
                collection.setUseYsNum(Integer.parseInt(values.get("saline_used").toString()));
            } catch (Exception e) {
            }

            //循环次数
            try {
                collection.setCycles(Integer.parseInt(values.get("collect_plasma_cycle_times").toString()));
            } catch (Exception e) {
            }

            //设定单程采量
            try {
                collection.setSetSingleLayerNum(Integer.parseInt(values.get("DCCL").toString()));
            } catch (Exception e) {
            }

            //设定总采量
            try {
                collection.setSetTotalNum(Integer.parseInt(values.get("ZCJL").toString()));
            } catch (Exception e) {
            }

            //设定总量差值
            try {
                collection.setSetTotalNumCz(Integer.parseInt(values.get("ZLCZ").toString()));
            } catch (Exception e) {
            }

            //设定袖带压力
            try {
                collection.setSetCuffPressure(Integer.parseInt(values.get("XDYL").toString()));
            } catch (Exception e) {
            }

            //设定采浆速度
            try {
                collection.setSetCollectingSpeed(Integer.parseInt(values.get("CJSD").toString()));
            } catch (Exception e) {
            }

            //设定还输速度
            try {
                collection.setSetHsSpeed(Integer.parseInt(values.get("HSSD").toString()));
            } catch (Exception e) {
            }

            //HCT值
            try {
                collection.setHtc(Float.parseFloat(values.get("donator_HCT").toString()));
            } catch (Exception e) {
            }

            //耗材安装时间
            try {
                String v = values.get("start_install_consumable").toString();
                if (AdscmBaseUtils.getInstance().isNotEmpty(v, null)) {
                    collection.setInstallStartTime(new Date(Long.parseLong(v)));
                }
            } catch (Exception e) {
            }
            try {
                String v = values.get("end_install_consumable").toString();
                if (AdscmBaseUtils.getInstance().isNotEmpty(v, null)) {
                    collection.setInstallEndTime(new Date(Long.parseLong(v)));
                }
            } catch (Exception e) {
            }
            try {
                collection.setInstallTaken((collection.getInstallEndTime().getTime() - collection.getInstallStartTime().getTime()) / 1000);

            } catch (Exception e) {
            }

            //耗材卸载时间
            try {
                String v = values.get("start_uninstall_consumable_time").toString();
                if (AdscmBaseUtils.getInstance().isNotEmpty(v, null)) {
                    collection.setUninstallStartTime(new Date(Long.parseLong(v)));
                }
            } catch (Exception e) {
            }
            try {
                String v = values.get("end_uninstall_consumable_time").toString();
                if (AdscmBaseUtils.getInstance().isNotEmpty(v, null)) {
                    collection.setUninstallEndTime(new Date(Long.parseLong(v)));
                }
            } catch (Exception e) {
            }
            try {
                collection.setUninstallTaken((collection.getUninstallEndTime().getTime() - collection.getUninstallStartTime().getTime()) / 1000);
            } catch (Exception e) {
            }

            //穿刺时间
            try {
                String v = values.get("start_puncturing_time").toString();
                if (AdscmBaseUtils.getInstance().isNotEmpty(v, null)) {
                    collection.setPunctureStartTime(new Date(Long.parseLong(v)));
                }
            } catch (Exception e) {
            }
            try {
                String v = values.get("end_puncturing_time").toString();
                if (AdscmBaseUtils.getInstance().isNotEmpty(v, null)) {
                    collection.setPunctureEndTime(new Date(Long.parseLong(v)));
                }
            } catch (Exception e) {
            }
            try {
                collection.setPunctureTaken((collection.getPunctureEndTime().getTime() - collection.getPunctureStartTime().getTime()) / 1000);
            } catch (Exception e) {
            }

            if (collection.getId() == null){
                providerCollectionMapper.insert(collection);
            }else {
                providerCollectionMapper.updateById(collection);
            }
            providerData.setCollectId(collection.getId());
            providerData.setCollectFinishTime(collection.getEndTime());
            providerQueue.updateProviderData(providerData);

            logger.info("【"+providerData.getProviderNo()+"："+providerData.getName()+"】采浆完成...");


//            try{
//                collection.setSynDate(AdscmDateUtils.getFormateDate(new Date()));
//                collection.setModifyTime(new Date());
//                collection.setIsDeal("1");
//                providerCollectionService.dealProviderCollection(collection);
//            }catch (Exception e){
//                logger.error("更新费用、热合、化检记录异常，请手动操作",e);
//            }

            //发送浆员状态给分配机
            MachineMgr.getInstance().sendMsgToAllotCtxs(BeanSupport.loadToAllotMsg(providerData,null));

            //发送结束采浆状态给平板
            values.put("plasma_finish_time",collection.getEndTime().getTime());
            this.doFinishedCollectPlasma(packet);

            //查询浆机状态
            ChannelHandlerContext macCtx = MachineMgr.getInstance().getMacCtx(collection.getMachineNo());
            SendMsgSupport.queryZxdcStatus(macCtx);
        } else {
            logger.error("没有获取到浆员[" + donor_id + "]的登记数据，不能更新采浆数据");
        }


    }

    /**
     * 处理浆机接收到分配浆员后的回调方法
     * @param packet
     */
    private void doAllocDonor(ZxdcMsgPacket packet){

        logger.info("接收到单采机上传的 response 信息："+packet);
        HashMap<String, Object> values = packet.getValues();
        String result = (String) values.get("result");

        Map<ChannelHandlerContext, ChannelHandlerContext> chairMacMap = NettyMsgHelper.getChairMacMap();
        ChannelHandlerContext chairCtx = chairMacMap.get(packet.getCtx());

        if (chairCtx != null){
            logger.info("接收到浆机上传的是否接收到平板端发送的认证成功信息："+result);
            chairMacMap.remove(packet.getCtx());
            SendMsgSupport.revAuthToChair(chairCtx);
        }else{
            if ("success".equals(result)){
                Map<ChannelHandlerContext, Boolean> mapAllot = NettyMsgHelper.getAllotSuccessMap();
                Map<ChannelHandlerContext, Boolean> mapCancel = NettyMsgHelper.getCancelAllotSuccessMap();
                Boolean isSuccessAllot = mapAllot.get(packet.getCtx());
                Boolean isSuccessCancel = mapCancel.get(packet.getCtx());
                if(isSuccessAllot != null){
                    mapAllot.put(packet.getCtx(),true);
                }
                if(isSuccessCancel != null){
                    mapCancel.put(packet.getCtx(),true);
                }
            }
        }


    }

    /**
     * 血浆重量
     * @param packet
     * @return
     */
    private ZxdcMsgPacket doWeight(ZxdcMsgPacket packet){
        ZxdcMsgPacket targetPacket = null;
        try {
            boolean ok = false;
            try {
                MachineData machineData = MachineMgr.getInstance().getMachine(packet.getCtx());
                String weight = TextUnit.ObjToString(packet.getValues().get("XJDZC_weight"));

                synchronized (MachineMgr.getInstance()) {
                    if (machineData != null) {
                        machineData.setWeight(Integer.parseInt(weight));
                        machineData.setOnline(true);
                        MachineMgr.getInstance().updateRedisMachineData(objectRedisTemplate,machineData);
                    }else{return null;}
                }

                ZxdcMsgPacket sendPacket = new ZxdcMsgPacket();
                sendPacket.setCmd("machine_weight");
                sendPacket.setHasResponse(false);
                sendPacket.setLevel(2);
                HashMap<String, Object> values = new HashMap<String, Object>();
                values.put("mcode", machineData.getCode());
                values.put("weight", Integer.parseInt(weight));
                sendPacket.setValues(values);
                MachineMgr.getInstance().sendMsgToAllotCtxs(sendPacket);

                //发送采浆重量给平板
                ChannelHandlerContext chairCtx = ChairMgr.getInstance().getCtxByChairsMcode(machineData.getCode());
                ZxdcMsgPacket chairPacket = new ZxdcMsgPacket();
                chairPacket.setCmd("plasma_weight");
                chairPacket.setHasResponse(false);
                chairPacket.setTimeout(30000);
                chairPacket.setLevel(2);
                HashMap<String, Object> values1 = new HashMap<String, Object>();
                values1.put("current_weight", Integer.parseInt(weight));
                chairPacket.setValues(values1);
                NettyMsgHelper.sendPacketToChair(chairCtx,chairPacket);

                ok = true;
            }catch (Exception e1){
                logger.error("发送耗材安装结束的消息给客户端失败", e1);
            }

            targetPacket = this.loadZxdcMsgPacket(packet,ok);
        }catch (Exception e){
            logger.error("结束安装耗材失败", e);
        }
        return targetPacket;
    }

    /**
     * 结束安装耗材（给平板发消息）
     * @param packet
     * @return
     */
    private ZxdcMsgPacket doFinishInstallCm(ZxdcMsgPacket packet) {
        ZxdcMsgPacket targetPacket = null;
        try {
            boolean ok = false;
            try {
                MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
                if (machine != null){
                    ChannelHandlerContext chairsCtx = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                    SendMsgSupport.finishInstallCm(chairsCtx,packet);
                    ok = true;
                }
            }catch (Exception e1){
                logger.error("发送耗材安装结束的消息给平板端失败", e1);
            }

             targetPacket = this.loadZxdcMsgPacket(packet,ok);
        }catch (Exception e){
            logger.error("结束安装耗材失败", e);
        }
        return targetPacket;
    }

    private ZxdcMsgPacket loadZxdcMsgPacket(ZxdcMsgPacket packet,boolean ok){
        ZxdcMsgPacket targetPacket = null;
        if (packet.isHasResponse()){
            targetPacket = new ZxdcMsgPacket();
            targetPacket.setSeq(packet.getSeq());
            targetPacket.setCmd("response");
            targetPacket.setResponseFromCmd(packet.getCmd());
            HashMap<String, Object> values = new HashMap<String, Object>();
            values.put("result", ok ? "success" : "failure");
            targetPacket.setValues(values);
        }

        return targetPacket;
    }

    /**
     * 开始安装耗材（给平板发消息）
     *
     * @param packet
     */
    private ZxdcMsgPacket doStartInstallCm(ZxdcMsgPacket packet) {
        ZxdcMsgPacket targetPacket = null;
        try {
            boolean ok = false;
            try {
                MachineData machine = MachineMgr.getInstance().getMachine(packet.getCtx());
                if (machine != null){
                    ChannelHandlerContext chairsCtx = ChairMgr.getInstance().getCtxByChairsMcode(machine.getCode());
                    SendMsgSupport.startInstallCm(chairsCtx,packet);
                    ok = true;
                }
            }catch (Exception e1){
                logger.error("发送耗材安装成功的消息给平板端失败", e1);
            }

            targetPacket = this.loadZxdcMsgPacket(packet,ok);
        }catch (Exception e){
            logger.error("安装耗材失败", e);
        }
        return targetPacket;
    }

    /**
     * 护士登录
     *
     * @param packet
     */
    private ZxdcMsgPacket doNurseRegister(ZxdcMsgPacket packet) {

        ZxdcMsgPacket targetPacket = new ZxdcMsgPacket();
        try {
            MachineData machineData = MachineMgr.getInstance().getMachine(packet.getCtx());

            targetPacket.setSeq(packet.getSeq());
            targetPacket.setCmd("response");
            targetPacket.setResponseFromCmd(packet.getCmd());

            HashMap<String, Object> values = new HashMap<String, Object>();

            Object nurseId = packet.getValues().get("nurseID");

            if (nurseId instanceof String && machineData != null) {
                logger.info(machineData.getCode() + " 护士登录：" + nurseId);
                //查询护士信息
//                values.put("nurse_no", nurse.getPersonid());
//                values.put("nurse_name", nurse.getPersonname());
//                values.put("age", DateUnit.calcAge(new Date(System.currentTimeMillis()), nurse.getBirthday()));
//                values.put("sex", nurse.getXmidDisplay());
//                values.put("address", nurse.getAddr());
//                if (photo != null) {
//                    values.put("photo", photo);
//                }
//                ok = true;


                String nId = (String)nurseId;
                JyUser user = jyUserMapper.selectById(nId);

                values.put("nurse_no", user.getId());
                values.put("nurse_name",user.getName());
                values.put("age", 0);
                String gender = user.getGender();
                if (AdscmBaseUtils.getInstance().isNotEmpty(gender,null)){
                    if ("1".equals(gender)){
                        gender = "男";
                    }else {
                        gender = "女";
                    }
                    values.put("sex", gender);
                }
                values.put("address", user.getAddress());

                String userPhoto = user.getPhoto();
                byte[] photo = null;
                if (AdscmBaseUtils.getInstance().isNotEmpty(userPhoto,null)){
//                    photo = AdscmSystemUtils.getInstance().getFileBytes(userPhoto);
                    photo = uploadService.downloadImageReturnBytes(userPhoto);
                }else {
                    photo = AdscmBaseUtils.getInstance().getNullNursePhoto();
                }
                if (photo == null){
                    photo = AdscmBaseUtils.getInstance().getNullNursePhoto();
                }
                photo = AdscmBaseUtils.getInstance().buildIcon(photo, 100, 100);
                values.put("photo", Base64.getEncoder().encodeToString(photo));
                values.put("result", "success");

                targetPacket.setValues(values);

                this.onNurseRegister(machineData,  user.getId()+"", user.getName());

                this.sendMacStatusToAllot(machineData);
            }


        } catch (Exception e) {
            logger.error("护士登录浆机失败", e);
        }

        return targetPacket;
    }

    /**
     * 护士登录后，修改缓存中的护士信息
     *
     * @param machineData
     * @param personcode
     * @param personname
     */
    private void onNurseRegister(MachineData machineData, String personcode, String personname) {

        synchronized (MachineMgr.getInstance()) {

            machineData.setNurseCode(personcode);
            machineData.setNurseName(personname);
            MachineMgr.getInstance().updateRedisMachineData(objectRedisTemplate,machineData);
            HashMap<String, Set<MachineData>> nurseMachineMap = MachineMgr.getInstance().getNurseMachineMap();

            Set<MachineData> set = nurseMachineMap.get(personcode);
            if (set == null) {
                set = new HashSet<MachineData>();
                nurseMachineMap.put(personcode, set);
            }
            set.add(machineData);
        }

    }


    /**
     * 浆机状态
     *
     * @param packet
     */
    private void doZxdcStatus(ZxdcMsgPacket packet) {

        try {
            String status = TextUnit.ObjToString(packet.getValues().get("cur_sys_state"));
            String plasma_floors = TextUnit.ObjToString(packet.getValues().get("plasma_floor"));

            MachineData machineData = MachineMgr.getInstance().getMachine(packet.getCtx());

            if (status != null && machineData != null) {
                int idx = Integer.parseInt(status);

                int floors = -1;
                if (AdscmBaseUtils.getInstance().isNotEmpty(plasma_floors,null)){
                    floors = Integer.parseInt(plasma_floors);
                }

                String text = getZxdcStatusText(idx,floors);
                logger.info(machineData.getCode() + " 浆机状态：" + text);
                synchronized (MachineMgr.getInstance()) {
                    if (idx >= 12/* || (idx <= 6 && machineData.getAllotTime() == null)*/) {
                        if (machineData.getStatus() == MachineData.FREE) {
                            return;
                        }
                        machineData.doFree();
                        //修改浆员缓存的状态（见softfan）

                    }
                    machineData.setRunStatus(idx);
                    machineData.setStatusInfo(text);
                    machineData.setOnline(true);
                    MachineMgr.getInstance().updateRedisMachineData(objectRedisTemplate,machineData);
                }

                this.sendMacStatusToAllot(machineData);


            } else {
                logger.info(machineData != null ? machineData.getCode():"" + " 浆机状态： 无");
            }


        } catch (Exception e) {
            logger.error("更新浆机状态失败", e);
        }
    }

    private void sendMacStatusToAllot(MachineData machineData){
        //通知客户端浆机的状态
//                System.out.println(":::::"+MachineMgr.getInstance().getMachineQueue());
        try {
            ZxdcMsgPacket msgPacket = new ZxdcMsgPacket();
            msgPacket.setCmd("machine_statusInfo");
            msgPacket.setHasResponse(false);
            msgPacket.setLevel(3);
            HashMap<String, Object> values = new HashMap<String, Object>();
            values.put("mcode", machineData.getCode());
            values.put("info", JSON.toJSONString(machineData, SerializerFeature.PrettyFormat));
            msgPacket.setValues(values);

            MachineMgr.getInstance().sendMsgToAllotCtxs(msgPacket);

        } catch (Exception e1) {
            logger.error("更新分配机显示的浆机状态失败...", e1);
        }
    }


}
